package org.farming.plants;
/**
 * Allotment, Plant class
 * @author DEADBEEF
 * @version 0.01a
 * @note Scarecrow will require a special case (can use any type of spare, and will be returned same type used)
 * @note Needs to collect/check rest of interact strings
**/
public class Allotments extends Plants
{
    /**
     * Holds all the information we have about each of the Allotment plants
     *
     * @param id, This is (usually) an offset used when calculating the stage of the plant. Unique
     * @param name, This is a reference that we can use to tell the player what they are farming
     * @param stages, How many growth stages from first planted to completly grown
     * @param seedId, Item id of the seed
     * @param seedString, Item string of the seed
     * @param itemId, Item id of the harvested allotment
     * @param itemString, Item string of the harvested allotment
     * @param interactString, String of the plant when grown
     * @param noteable, Boolean of whether the leprechaun will note the harvested item
    **/
    public static enum Allotment implements Plants.PlantEnum {
        UNKNOWN    ( -3, "UNKNOWN",    0,  -1, -1,   "Unknown",         0,    "Unknown",    "",           false ), 
        NONE       ( -2, "None",       0,  -1, -1,   "None",            0,    "None",       "",           false ), 
        WEEDS      ( -1, "Weeds",      0,  -1, -1,   "Weeds",           6055, "Weeds",      "",           false ), 
        EMPTY      ( 0,  "Empty",      0,  -1, -1,   "Empty",           0,    "Empty",      "",           false ), 
        POTATO     ( 5,  "Potato",     1,  5,  7549, "Potato seed",     6010, "Potato",     "Potato",     true  ), 
        ONION      ( 12, "Onion",      5,  5,  5319, "Onion seed",      1957, "Onion",      "Onion",      true  ), 
        CABBAGE    ( 19, "Cabbage",    7,  5,  5324, "Cabbage seed",    1965, "Cabbage",    "Cabbage",    true  ),
        TOMATO     ( 26, "Tomato",     12, 5,  5322, "Tomato seed",     1982, "Tomato",     "Tomato",     true  ),
        SWEETCORN  ( 33, "Sweetcorn",  20, 6,  5320, "Sweetcorn seed",  5986, "Sweetcorn",  "Sweetcorn",  true  ),
        STRAWBERRY ( 42, "Strawberry", 31, 7,  5323, "Strawberry seed", 5504, "Strawberry", "Strawberry", true  ),
        WATERMELON ( 51, "Watermelon", 47, 8,  5321, "Watermelon seed", 5982, "Watermelon", "Watermelon", true  );
        
        private final int id, level, stages, seedId, itemId;   
        private final String seedString, itemString, interactString, name; 
        private final boolean canNote;   

        /**
         * Allotment Enum
         * Interface params
         * @param id Our unique id and offset for the plant
         * @param name The reference for this plant which we can display to the user
         * @param level The farming level required to plant
         * @param stages How many growth stages the plant has (from first planted to harvestable inclusive)
         * @param seedId, Item id of the seed
         * @param seedString, Item string of the seed
         * @param itemId, Item id of the harvested plant
         * @param itemString, Item string of the harvested plant
         * @param interactString, String of the plant when grown
         * @param canNote, Whether the leprechaun can note this plant (noted item id's are +1 of the regular id)
         * Local params
        **/
        Allotment(
            int id, 
            String name,
            int level, 
            int stages, 
            int seedId, 
            String seedString, 
            int itemId, 
            String itemString, 
            String interactString, 
            boolean canNote
        ) {
            this.id              = id;
            this.name            = name;
            this.level           = level;
            this.stages          = stages;
            this.seedId          = seedId;
            this.itemId          = itemId;
            this.seedString      = seedString;
            this.itemString      = itemString;
            this.interactString  = interactString;
            this.canNote         = canNote;
        }
        
        //Interface methods
        public int id()                 {return id;}
        public int level()              {return level;}
        public int stages()             {return stages;}
        public int seedId()             {return seedId;}
        public int itemId()             {return itemId;}
        public String seedString()      {return seedString;}
        public String itemString()      {return itemString;}
        public String interactString()  {return interactString;}
        public boolean canNote()        {return canNote;}
        public int noteId()             {return canNote?(itemId+1):itemId;}
        public String toString()        {return name;}
        //Local methods
    }

    /**
     * This was designed to be a static method, however static and abstract don't mix so this will have to do
     * 
     * @param bits The byte for the herb patch we want the state for
     * @return The calculated state enum
    **/
    public State getState(int bits)
    {
        bits = bits&255;//Cleanse
        int stateBits = (bits&192)>>6;//Get 7&8th bits
        int plantBits = bits&63;//Clear 7&8th bits
        if(stateBits==0x00){
            Allotment p = getPlant(bits);
            if(getStagePlant(p,plantBits)==p.stages()){ return State.READY;
            }else{                                      return State.GROWING;}
        }else if(stateBits==0x01){                      return State.WATERED;
        }else if(stateBits==0x02){                      return State.DISEASED;
        }else if(stateBits==0x03){                      return State.DEAD;
        }else{                                          return State.UNKNOWN;}
    }
    
    /**
     * This was designed to be a static method, however static and abstract don't mix so this will have to do
     * 
     * @param bits The byte for the herb patch we want the plant for
     * @return The calculated plant enum
    **/
    public Allotment getPlant(int bits)
    {
        bits = bits&255;//Cleanse
        int stateBits = (bits&192)>>6;//Get 7&8th bits
        int plantBits = bits&63;//Clear 7&8th bits
        if(bits>=0xAA&&bits<=0xAC){                                     return Allotment.NONE;//Dead, can't id plant
        }else if((stateBits==0)&&((plantBits==0x03))){                  return Allotment.EMPTY;
        }else if((stateBits==0)&&(plantBits>=0x00)&&(plantBits<=0x02)){ return Allotment.WEEDS;
        }else if((plantBits>=0x06)&&(plantBits<=0x0C)){                 return Allotment.POTATO;
        }else if((plantBits>=0x0D)&&(plantBits<=0x13)){                 return Allotment.ONION;
        }else if((plantBits>=0x14)&&(plantBits<=0x1A)){                 return Allotment.CABBAGE;
        }else if((plantBits>=0x1B)&&(plantBits<=0x21)){                 return Allotment.TOMATO;
        }else if((plantBits>=0x22)&&(plantBits<=0x2A)){                 return Allotment.SWEETCORN;
        }else if((plantBits>=0x2B)&&(plantBits<=0x33)){                 return Allotment.STRAWBERRY;
        }else if((plantBits>=0x34)&&(plantBits<=0x3E)){                 return Allotment.WATERMELON;
        }else{                                                          return Allotment.UNKNOWN;}
    }
    
    /**
     * This was designed to be a static method, however static and abstract don't mix so this will have to do
     * 
     * @param bits The byte for the herb patch we want the stage for
     * @return The calculated stage
    **/
    public int getStage(int bits)
    {
        bits = bits&255;//Cleanse
        int plantBits = bits&63;//Clear 7&8th bits
        return getStagePlant(getPlant(bits), plantBits);
    }
    private int getStagePlant(Allotment plant, int plantBits)
    {
        switch(plant)
        {
            case UNKNOWN:
                return 0;
            default:
                return ((plantBits-plant.id())>plant.stages())?plant.stages():(plantBits-plant.id());
        }
    }
}
/*
## Allotment
format: sspp pppp
- plant types and growth states (p bits):
-- 0x00 - 0x03: layers of weeds removed (0x00 meaning no weeds removed, 0x03 meaning all weeds removed), iff both state bits are 0
-- 0x06 - 0x0c: 6

-- 0x0d - 0x13: onion 13 
-- 0x14 - 0x1a: cabbage 20
-- 0x1b - 0x21: tomato 27
-- 0x22 - 0x2a: sweetcorn 34
-- 0x2b - 0x33: strawberry 43
-- 0x34 - 0x3e: watermelon 52
- states (s bits):
-- 0x00: growing
-- 0x01: watered
-- 0x02: diseased
-- 0x03: dead

locations:
- falador, bits 0-15 of 504
- catherby, bits 16-31 of 504
- ardougne, bits 0-15 of 505
- port phasmatys, bits 16-31 of 505
*/